import {
  Count,
  CountSchema,
  Filter,
  repository,
  Where,
} from '@loopback/repository';
import {
  post,
  param,
  get,
  getFilterSchemaFor,
  getWhereSchemaFor,
  patch,
  put,
  del,
  requestBody,
} from '@loopback/rest';
import { ChannelUser, User } from '../models';
import { ChannelUserRepository, UserRepository, ConfigRepository } from '../repositories';
import { getCurTimestamp } from '../utils/utils';
import { authenticate } from '@loopback/authentication';

export class ChannelUserController {
  constructor(
    @repository(ChannelUserRepository)
    public channelUserRepository: ChannelUserRepository,
    @repository(UserRepository)
    public userRepository: UserRepository,
    @repository(ConfigRepository)
    public configRepository: ConfigRepository,
  ) { }

  @post('/channelUsers', {
    responses: {
      '200': {
        description: 'ChannelUser model instance',
        content: { 'application/json': { schema: { 'x-ts-type': ChannelUser } } },
      },
    },
  })
  @authenticate('jwt')
  async create(@requestBody() channelUser: ChannelUser): Promise<ChannelUser> {
    channelUser.createTime = getCurTimestamp()
    channelUser.linkDesc = `h5/channel/${channelUser.name}`;
    return await this.channelUserRepository.create(channelUser);
  }

  @get('/channelUsers/count', {
    responses: {
      '200': {
        description: 'ChannelUser model count',
        content: { 'application/json': { schema: CountSchema } },
      },
    },
  })
  @authenticate('jwt')
  async count(
    @param.query.object('where', getWhereSchemaFor(ChannelUser)) where?: Where,
  ): Promise<Count> {
    return await this.channelUserRepository.count(where);
  }

  @get('/channelUsers', {
    responses: {
      '200': {
        description: 'Array of ChannelUser model instances',
        content: {
          'application/json': {
            schema: { type: 'array', items: { 'x-ts-type': ChannelUser } },
          },
        },
      },
    },
  })
  @authenticate('jwt')
  async find(
    @param.query.object('filter', getFilterSchemaFor(ChannelUser)) filter?: Filter,
  ): Promise<ChannelUser[]> {
    var channelUsers = await this.channelUserRepository.find(filter);
    var conf = await this.configRepository.findOne({where: {key: 'channelHost'}});
    if (conf == null) {
      return channelUsers;
    }
    for (const iter of channelUsers) {
      iter.linkDesc = 'H5推广：' + conf.value + '/' + iter.linkDesc;
    }
    return channelUsers;
  }

  @patch('/channelUsers', {
    responses: {
      '200': {
        description: 'ChannelUser PATCH success count',
        content: { 'application/json': { schema: CountSchema } },
      },
    },
  })
  @authenticate('jwt')
  async updateAll(
    @requestBody() channelUser: ChannelUser,
    @param.query.object('where', getWhereSchemaFor(ChannelUser)) where?: Where,
  ): Promise<Count> {
    return await this.channelUserRepository.updateAll(channelUser, where);
  }

  @get('/channelUsers/{id}', {
    responses: {
      '200': {
        description: 'ChannelUser model instance',
        content: { 'application/json': { schema: { 'x-ts-type': ChannelUser } } },
      },
    },
  })
  @authenticate('jwt')
  async findById(@param.path.number('id') id: number): Promise<ChannelUser> {
    return await this.channelUserRepository.findById(id);
  }

  @patch('/channelUsers/{id}', {
    responses: {
      '204': {
        description: 'ChannelUser PATCH success',
      },
    },
  })
  @authenticate('jwt')
  async updateById(
    @param.path.number('id') id: number,
    @requestBody() channelUser: ChannelUser,
  ): Promise<void> {
    console.log("updateById id:", id, "channelUser:", channelUser);
    await this.channelUserRepository.updateById(id, channelUser);
  }

  @put('/channelUsers/{id}', {
    responses: {
      '204': {
        description: 'ChannelUser PUT success',
      },
    },
  })
  @authenticate('jwt')
  async replaceById(
    @param.path.number('id') id: number,
    @requestBody() channelUser: ChannelUser,
  ): Promise<void> {
    console.log("replaceById id:", id, "channelUser:", channelUser);
    await this.channelUserRepository.replaceById(id, channelUser);
  }

  @del('/channelUsers/{id}', {
    responses: {
      '204': {
        description: 'ChannelUser DELETE success',
      },
    },
  })
  @authenticate('jwt')
  async deleteById(@param.path.number('id') id: number): Promise<void> {
    // await this.channelUserRepository.deleteById(id);
    await this.channelUserRepository.dataSource.execute(`update ChannelUser set status=0 where id=${id}`)
  }

  @get('/channelUsers/regInfo', {
    responses: {
      '200': {
        description: '该渠道下用户注册信息',
        content: { 'application/json': { schema: { 'x-ts-type': {} } } },
      },
    },
  })
  @authenticate('jwt')
  async findRegInfoById(
    @param.query.object('filter', getFilterSchemaFor(User)) filter?: Filter,
  ): Promise<any> {
    if (!filter) {
      filter = { fields: { id: true, phone: true, clientType: true, status: true, createTime: true } }
    } else {
      filter.fields = { id: true, phone: true, clientType: true, status: true, createTime: true }
    }
    return await this.userRepository.find(filter)
  }

  @get('/channelUsers/{id}/activeStat', {
    responses: {
      '200': {
        description: '该渠道下用户激活统计信息',
        content: { 'application/json': { schema: { 'x-ts-type': {} } } },
      },
    },
  })
  @authenticate('jwt')
  async getChannelUserActiveStat(
    @param.path.number('id') id: number,
    @param.query.number('startTime') startTime: number,
    @param.query.number('endTime') endTime: number,
  ): Promise<any> {
    if (!id) {
      return []
    }

    let whereTime = ""
    if (startTime && endTime) {
      whereTime = `User.createTime>=${startTime} and User.createTime<=${endTime} and `
    }

    // and DATE_FORMAT(
    //   FROM_UNIXTIME(User.createTime),
    //   '%Y-%m-%d'
    // ) = DATE_FORMAT(
    //   FROM_UNIXTIME(ApplyRecord.createTime),
    //   '%Y-%m-%d'
    // )
    let sql = `
      select
        count(
          DISTINCT(User.id)
        ) AS regCnt,
        count(
          DISTINCT(User.id),
          if(User.status = 1, true, null)
        ) AS activeCnt,
        count(
          DISTINCT(CONCAT(ApplyRecord.userId,ApplyRecord.loanProductId,DATE_FORMAT(FROM_UNIXTIME(ApplyRecord.createTime),'%Y-%m-%d')))
        ) AS applyCnt,
        DATE_FORMAT(
          FROM_UNIXTIME(User.createTime),
          '%Y-%m-%d'
        ) as date
      from
        User
        left join ApplyRecord on User.id = ApplyRecord.userId
      where
        ${whereTime}User.channelId=${id}
      group by
        date
      order by date desc
    `
    let result = await this.channelUserRepository.dataSource.execute(sql)

    console.log(sql);

    for (var i = 0; i < result.length; i++) {
      result[i].regCnt = ~~result[i].regCnt;
      result[i].activeCnt = ~~result[i].activeCnt;
      result[i].applyCnt = ~~result[i].applyCnt;
    }

    return result;
  }

  @get('/channelUsers/{id}/activeStat2', {
    responses: {
      '200': {
        description: '该渠道下用户激活统计信息',
        content: { 'application/json': { schema: { 'x-ts-type': {} } } },
      },
    },
  })
  @authenticate('jwt')
  async getChannelUserActiveStat2(
    @param.path.number('id') id: number,
    @param.query.number('startTime') startTime: number,
    @param.query.number('endTime') endTime: number,
  ): Promise<any> {
    if (!id) {
      return []
    }

    let whereTime = ""
    if (startTime && endTime) {
      whereTime = `dateTime>=${startTime} and dateTime<=${endTime} and `
    }

    let result = await this.channelUserRepository.dataSource.execute(`
      SELECT
        registerCnt AS regCnt,
        activeCnt,
        realRegisterCnt AS realRegCnt,
        realActiveCnt,
        DATE_FORMAT(dateTime,'%Y-%m-%d') AS date
      FROM
        ChannelDailyDownStat
      WHERE
        ${whereTime}channelId=${id}
      ORDER BY
        dateTime desc
    `)

    for (var i = 0; i < result.length; i++) {
      result[i].regCnt = ~~result[i].regCnt;
      result[i].activeCnt = ~~result[i].activeCnt;
      result[i].realRegCnt = ~~result[i].realRegCnt;
      result[i].realActiveCnt = ~~result[i].realActiveCnt;
    }

    return result;
  }
}
